package br.ufmt.model;

import java.util.Calendar;
import java.util.Date;
import java.util.ArrayList;
import java.util.GregorianCalendar;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import br.ufmt.exception.LocacaoException;

/**
 * Respons�vel por registrar a loca��o/empr�stimo das m�dias.
 * @author jppreti
 *
 */
@ManagedBean
@SessionScoped
public class Locacao {

	public ArrayList<Locacao> locacoes = new ArrayList<Locacao>();
	/**
	 * Data em que a loca��o ocorreu
	 */
	private Date dataLocacao;
	/**
	 * quem � o cliente ou a pessoa que ir� levar as m�dias
	 */
	private Pessoa locatario;
	/**
	 * qual o funcion�rio respons�vel pelo atendimento/loca��o
	 */
	private Funcionario funcionario;
	/**
	 * data em que foi realizado o pagamento da loca��o
	 */
	private Date dataPagamento;
	/**
	 * itens que foram locados
	 * @see locadora.LocacaoItem
	 */
	private static ArrayList<LocacaoItem> itensLocados = new ArrayList<LocacaoItem>();
	
	public Locacao(){
		
	}
	
	public Locacao(Date dataLocacao, Pessoa locatario, Funcionario funcionario) throws LocacaoException {
		setDataLocacao(dataLocacao);
		setLocatario(locatario);
		setFuncionario(funcionario);
	}
	
	public Date getDataPagamento() {
		return dataPagamento;
	}

	public Date getDataLocacao() {
		return dataLocacao;
	}
	
	public Pessoa getLocatario() {
		return locatario;
	}
	
	public Funcionario getFuncionario() {
		return funcionario;
	}
	
	/**
	 * Modifica a data em que ocorreu o pagamento da loca��o
	 * @param dataPagamento
	 */
	public void setDataPagamento(Date dataPagamento) {
		this.dataPagamento = dataPagamento;
	}
	
	/**
	 * Modifica a data em que a loca��o ocorreu
	 * @param dataLocacao
	 * @throws LocacaoException
	 */
	public void setDataLocacao(Date dataLocacao) throws LocacaoException {
		if (dataLocacao==null) throw new LocacaoException(LocacaoException.DATA_LOCACAO_OBRIGATORIA);
		this.dataLocacao = dataLocacao;
	}
	
	/**
	 * Modifica o cliente que realizou a loca��o
	 * @param locatario
	 * @throws LocacaoException
	 */
	public void setLocatario(Pessoa locatario) throws LocacaoException {
		if (locatario==null) throw new LocacaoException(LocacaoException.LOCATARIO_OBRIGATORIO);
		this.locatario = locatario;
	}
	
	/**
	 * Modifica o funcion�rio que realizou a opera��o de loca��o
	 * @param funcionario
	 * @throws LocacaoException
	 */
	public void setFuncionario(Funcionario funcionario) throws LocacaoException {
		if (funcionario==null) throw new LocacaoException(LocacaoException.FUNCIONARIO_OBRIGATORIO);
		this.funcionario = funcionario;
	}

	/**
	 * Guarda uma refer�ncia do objeto em um vetor
	 */
	public void salvar() {
		if (!locacoes.contains(this))
			locacoes.add(this);
	}
	
	/**
	 * Remove a refer�ncia do objeto do vetor
	 */
	public void excluir() {
		locacoes.remove(this);
	}
	
	/**
	 * 
	 * @return true caso j� tenha sido pago e false caso contr�rio
	 */
	public boolean isPago() {
		return getDataPagamento()!=null;
	}
	
	/**
	 * 
	 * @return valor total das multas da loca��o
	 */
	public float getMulta() {
		float total = 0;
		for (LocacaoItem item : itensLocados) {
			total += item.getMulta();
		}
		return total;		
	}

	/**
	 * 
	 * @return o valor total da loca��o, considerando o valor total de cada item locado
	 */
	public float getValorTotal() {
		float total = 0;
		for (LocacaoItem item : itensLocados) {
			total += item.getValorTotal();
		}
		return total;
	}
	
	/**
	 * 
	 * @return true caso a loca��o ainda tenha itens a serem devolvidos e false caso
	 *         contr�rio
	 */
	public boolean isAberta() {
		for (LocacaoItem item : itensLocados) {
			if (!item.isDevolvido()) return true;
		}
		return false;
	}

	/**
	 * Realiza a loca��o de um determinado item (m�dia)
	 * @param midia midia que est� sendo locada
	 */
	public static void locarMidia(Midia midia) {
		float valorLocacao = TabelaPreco.getValorLocacao(midia);
		Calendar calendar = GregorianCalendar.getInstance();
		calendar.add(Calendar.HOUR, midia.getObra().getRotulo().getTempoDevolucao());
		LocacaoItem item = new LocacaoItem(midia,calendar.getTime(), valorLocacao);
		itensLocados.add(item);	
	}	
	
	/**
	 * Retira uma loca��o, caso tenha sido adicionada erroneamente
	 * @param item item a ser removido da loca��o
	 */
	public void removeLocacaoItem(LocacaoItem item) {
		itensLocados.remove(item);
	}
	
	/**
	 * 
	 * @param midia midia que est� sendo devolvida
	 */
	public void realizarDevolucao(Midia midia) {
		for (LocacaoItem item : itensLocados) {
			if (item.getMidiaLocada().equals(midia)) {
				item.setDataDevolvida(new Date());
				break;
			}
		}		
	}
	
	

	public ArrayList<LocacaoItem> getItensLocados() {
		return itensLocados;
	}

	public void setItensLocados(ArrayList<LocacaoItem> itensLocados) {
		Locacao.itensLocados = itensLocados;
	}



	static {
		Locacao locacao;
		try {
			locacao = new Locacao(new Date(),Cliente.getClientePorCpf("321.123.321-31"),Funcionario.getFuncionarioPorCpf("123.123.12-12"));
			locacao.locarMidia(Midia.getMidia(Obra.getObraPorNome("Matrix 1"), MidiaEnum.BD));
			locacao.locarMidia(Midia.getMidia(Obra.getObraPorNome("Immortals"), MidiaEnum.BD));
			locacao.realizarDevolucao(Midia.getMidia(Obra.getObraPorNome("Matrix 1"), MidiaEnum.BD));
			locacao.salvar();
			locacao = new Locacao(new Date(),Cliente.getClientePorCpf("321.123.321-31"),Funcionario.getFuncionarioPorCpf("123.123.12-13"));
			locacao.locarMidia(Midia.getMidia(Obra.getObraPorNome("Matrix 1"), MidiaEnum.DVD));
			locacao.locarMidia(Midia.getMidia(Obra.getObraPorNome("Immortals"), MidiaEnum.BD));
			locacao.locarMidia(Midia.getMidia(Obra.getObraPorNome("F�ria de Tit�s 2"), MidiaEnum.BD));
			locacao.realizarDevolucao(Midia.getMidia(Obra.getObraPorNome("Immortals"), MidiaEnum.BD));
			locacao.salvar();
		} catch (LocacaoException e) {
			e.printStackTrace();
		}			
	}	
}
